package main

import (
	"fmt"
	"log"
	"net"
	"strings"
)

// 使用Go语言完成WebServer基本功能代码，并能使用浏览器访问到网页。请简述浏览器发起请求到看到网页的整个过程

/*
DNS 查询：
	浏览器通过 DNS 查询将域名解析为 IP 地址。如果是 localhost 或 127.0.0.1，直接使用本地地址。

建立 TCP 连接：
	浏览器与服务器建立 TCP 连接，通常是通过 TCP/IP 协议，默认端口是 80（HTTP）或 443（HTTPS）。在这里，你的 Web 服务器监听的是 9999 端口。

发送 HTTP 请求：
	浏览器向服务器发送 HTTP 请求，通常是 GET 请求，请求 URL（如 http://localhost:9999）。
	请求示例：
		GET / HTTP/1.1
		Host: localhost:9999
		Connection: keep-alive

服务器处理请求：
	服务器接收到请求后，解析 HTTP 请求，并根据请求生成响应。
	服务器会返回一个 HTTP 响应头，包含状态码、内容类型、内容长度等信息，然后是响应体（网页内容）。

浏览器展示网页：
	浏览器接收到 HTTP 响应后，解析 HTML 内容，并渲染为可视化的网页。

关闭连接：
	服务器发送完数据后关闭连接，或者根据 HTTP 协议的版本（如 keep-alive）维持连接，等待更多请求。

*/

const response_body = `<!DOCTYPE html>
	<html lang="en">
	  <head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Web Server-Goroutine</title>
	  </head>
	  <body>
		<h2 style="color: blue">Welcome to the Echo Server</h2>
	  </body>
	</html>
	`
const response_header = `HTTP/1.1 200 OK
	Date: Mon, 27 Jul 2009 12:28:53 GMT
	Content-Type: text/html; charset=UTF-8
	Content-Length: %d
	Connection: close
	Server: YZY.com
	
	%s`

var response = fmt.Sprintf(
	strings.ReplaceAll(response_header, "\n", "\r\n"),
	len(response_body), response_body,
)

func main() {
	laddr, err := net.ResolveTCPAddr("tcp4", "0.0.0.0:9999")
	if err != nil {
		log.Fatal(err)
	}
	server, err := net.ListenTCP("tcp4", laddr)
	if err != nil {
		log.Fatal(err)
	}
	defer server.Close()

	for {
		conn, err := server.Accept()
		if err != nil {
			log.Println(err)
			continue
		}

		go func(conn net.Conn) {
			defer conn.Close()
			buffer := make([]byte, 4096)
			n, err := conn.Read(buffer)
			if err != nil {
				log.Println(err)
				return
			}
			if n == 0 {
				return
			}
			data := buffer[:n]
			request_first, _, _ := strings.Cut(string(data), "\r\n")
			fmt.Println("Request received:", string(data))

			firstLine := strings.Split(request_first, " ")
			path := firstLine[1]
			fmt.Println("Path:", path)

			// 处理不同的路径
			if path == "/hello" {
				conn.Write([]byte(response))
			} else {
				conn.Write([]byte("HTTP/1.1 404 Not Found\r\n"))
			}
		}(conn)
	}
}
